package com.why.search.service.impl;

import com.why.search.Vo.SearchParam;
import com.why.search.Vo.SearchResult;
import com.why.search.config.GuliESConfig;
import com.why.search.constant.EsConstant;
import com.why.search.service.MallService;
import org.apache.commons.lang.StringUtils;
import org.apache.lucene.search.join.ScoreMode;
import org.elasticsearch.action.search.SearchRequest;
import org.elasticsearch.action.search.SearchRequestBuilder;
import org.elasticsearch.action.search.SearchResponse;
import org.elasticsearch.client.RestHighLevelClient;
import org.elasticsearch.index.query.BoolQueryBuilder;
import org.elasticsearch.index.query.NestedQueryBuilder;
import org.elasticsearch.index.query.QueryBuilders;
import org.elasticsearch.index.query.RangeQueryBuilder;
import org.elasticsearch.search.builder.SearchSourceBuilder;
import org.elasticsearch.search.sort.SortOrder;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;

import javax.annotation.Resource;
import java.io.IOException;
import java.util.Objects;

/**
 * @program: why-gulimall
 * @description:
 * @author: @why
 * @create: 2021-06-04 09:16
 **/
@Service
public class MallServiceImpl implements MallService {
    @Resource
    private RestHighLevelClient client;


    @Override
    public SearchResult search(SearchParam param) {

        SearchResult result = null;


        SearchRequest searchRequest = BuilderSearchRequest(param);

        try {
            //执行查询操作
            SearchResponse response = client.search(searchRequest, GuliESConfig.COMMON_OPTIONS);


            //封装成我们需要的格式


            result = BuilderSearchResponse(response);

        } catch (IOException e) {
            e.printStackTrace();
        }


        return null;
    }

    /**
     * 封装响应数据
     *
     * @param response
     * @return
     */
    private SearchResult BuilderSearchResponse(SearchResponse response) {


        return null;
    }


    /**
     * 准备检索请求
     * 排
     *
     * @param param
     * @return
     */
    private SearchRequest BuilderSearchRequest(SearchParam param) {
        SearchSourceBuilder builder = new SearchSourceBuilder();
        /**
         * 查询条件：模糊匹配，过濾（按照属性，分类，品牌，价格区间，库存）
         */

//        1.外层开始，构建一个bool
        BoolQueryBuilder boolQueryBuilder = QueryBuilders.boolQuery();
//        1.1 构建一个must  按照skuTitile查询
        if (StringUtils.isNotEmpty(param.getKeyword())) {
            boolQueryBuilder.must(QueryBuilders.matchQuery("skuTitle", param.getKeyword()));
        }
//        1.2 构建一个filter  按照三级分类的id进行查询

        if (StringUtils.isNotEmpty(param.getCatelog3Id().toString())) {
            boolQueryBuilder.filter(QueryBuilders.termQuery("catelogId", param.getCatelog3Id().toString()));
        }
//        1.3 构建filter 按照品牌的id查询
        if (Objects.nonNull(param.getBrandId())) {

            boolQueryBuilder.filter(QueryBuilders.termsQuery("brandId", param.getBrandId()));
        }
//       1.4 // TODO: 2021/6/5    按照属性查询

        if (Objects.nonNull(param.getAttrs()) && param.getAttrs().size() > 0) {
//           NestedQueryBuilder使用的bool查询
            BoolQueryBuilder attrBool = QueryBuilders.boolQuery();
//            规定 attr =1_5寸:8寸     1是attr的id   后面则是id对应的属性
            for (String attr : param.getAttrs()) {

                String[] strings = attr.split("_");
                String attrId = strings[0];
                String[] attrDatas = strings[1].split(":");
                attrBool.must(QueryBuilders.termQuery("attrs.attrId", attrId));
                attrBool.must(QueryBuilders.termQuery("attr.attrValue", attrDatas));
//                每一个都要生成一个嵌入式的查询，因此需要放在for里面
                NestedQueryBuilder nestedQueryBuilder = QueryBuilders.nestedQuery("attrs", attrBool, ScoreMode.None);
                boolQueryBuilder.filter(nestedQueryBuilder);
            }
        }

//        1.5 按照是否有库存进行查询
        if (Objects.nonNull(param.getHasStock())) {

            boolean flag = param.getHasStock() == 1;
            boolQueryBuilder.filter(QueryBuilders.termQuery("hasStock", flag));
        }

//        1.6 按照价格区间查询   skuPrice =1_500/_500/500_  定义1_500指的是价格在1-->500之间   _500是小于 500_是大于500

        if (Objects.nonNull(param.getSkuPrice())) {
            String skuPrice = param.getSkuPrice();

            String[] prices = skuPrice.split("_");
//            如果这个是一个区间，那就说明是区间查询
            if (prices.length == 2) {
                RangeQueryBuilder rangeQuery = QueryBuilders.rangeQuery("skuPrice");
                rangeQuery.gte(prices[0]);
                rangeQuery.lte(prices[1]);
            } else if (prices.length == 1) {
                if (skuPrice.startsWith("_")) {
                    RangeQueryBuilder rangeQuery = QueryBuilders.rangeQuery("skuPrice");
                    rangeQuery.lte(prices[0]);
                } else if (skuPrice.endsWith("_")) {
                    RangeQueryBuilder rangeQuery = QueryBuilders.rangeQuery("skuPrice");
                    rangeQuery.gte(prices[0]);
                }

            }
        }

        builder.query(boolQueryBuilder);
        /**
         * 序，分页，高亮，聚合分析
         */

//        2.1 排序
        if (StringUtils.isNotEmpty(param.getSort())) {
            // sort= 字段_asc/desc
            String sort = param.getSort();

            String[] sorts = sort.split("_");

            if (sorts[1].equals(SortOrder.ASC.toString())) {
                builder.sort(sorts[0], SortOrder.ASC);
            } else {
                builder.sort(sorts[0], SortOrder.DESC);
            }

        }


        SearchRequest request = new SearchRequest(new String[]{EsConstant.PRODUCT_INDEX}, builder);
        return request;


    }
}
